package com.example.xch.scanzxing;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.Toast;

import com.example.xch.scanzxing.zxing.android.BeepManager;
import com.example.xch.scanzxing.zxing.decode.DecodeThread;
import com.example.xch.scanzxing.zxing.view.ViewfinderResultPointCallback;
import com.example.xch.scanzxing.zxing.view.ViewfinderView;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.Result;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

public class PmZxingActivity extends Activity implements TextureView.SurfaceTextureListener {
    private static final String TAG = "PmZxingActivity";

    private static final int PERMISSION_REQUEST_CODE = 100;//拍照请求码
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,//写权限
            Manifest.permission.CAMERA, //照相权限
            Manifest.permission.RECORD_AUDIO
    };

    // For Zxing
    private static final int MIN_FRAME_WIDTH = 240;
    private static final int MIN_FRAME_HEIGHT = 240;
    private static final int MAX_FRAME_WIDTH = 1200; // = 5/8 * 1920
    private static final int MAX_FRAME_HEIGHT = 675; // = 5/8 * 1080
    private Rect framingRect;
    private Rect framingRectInPreview;
    private Collection<BarcodeFormat> decodeFormats;
    private Map<DecodeHintType, ?> decodeHints;
    private String characterSet;
    private DecodeThread mDecodeThread;
    // 声音、震动控制
    private BeepManager beepManager;

    // For Camera2
    private static final int PREVIEW_WIDTH = 1920;                                        //预览的宽度
    private static final int PREVIEW_HEIGHT = 1200;                                       //预览的高度
    private Point cameraResolution = new Point(1920, 1080);

    private CameraCharacteristics mCameraCharacteristics;
    private int mCameraSensorOrientation = 0;
    private boolean canTakePic = true;                        //是否可以拍照
    private TextureView mTextureView;
    private ViewfinderView mViewfinderView;
    private CameraManager mCameraManager;//摄像头管理器
    private Handler mCameraHandler;
    private HandlerThread handlerThread;
    private Handler mDecodeHandler;

    private int mCameraID = CameraCharacteristics.LENS_FACING_FRONT;  //摄像头Id 0 为后  1 为前
    private ImageReader mImageReader;
    private CameraCaptureSession mCameraCaptureSession;
    private CameraDevice mCameraDevice;
    private Size mPreviewSize = new Size(PREVIEW_WIDTH, PREVIEW_HEIGHT);            //预览大小
    private Size mSavePicSize = new Size(PREVIEW_WIDTH, PREVIEW_HEIGHT);            //保存图片大小

    public ViewfinderView getViewfinderView() { return mViewfinderView; }
    public void drawViewfinder() { mViewfinderView.drawViewfinder(); }
    public CameraManager getCameraManager() { return mCameraManager; }
    public Handler getHandler() { return mDecodeHandler; }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /*
        requestWindowFeature(Window.FEATURE_NO_TITLE);//remove title bar  即隐藏标题栏
        getSupportActionBar().hide();// 隐藏ActionBar
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);//remove notification bar  即全屏
        */
        setContentView(R.layout.capture);

        hideSystemUI();

        beepManager = new BeepManager(this);

        handlerThread = new HandlerThread("CameraThread");
        handlerThread.start();
        mCameraHandler = new Handler(handlerThread.getLooper());

        mDecodeHandler = new Handler(getMainLooper()){
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case R.id.decode_succeeded:
                        Bundle bundle = msg.getData();
                        Bitmap barcode = null;
                        float scaleFactor = 1.0f;
                        if (bundle != null) {
                            byte[] compressedBitmap = bundle.getByteArray(DecodeThread.BARCODE_BITMAP);
                            if (compressedBitmap != null) {
                                barcode = BitmapFactory.decodeByteArray(compressedBitmap,
                                        0, compressedBitmap.length, null);
                                barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);
                            }
                            scaleFactor = bundle.getFloat(DecodeThread.BARCODE_SCALED_FACTOR);
                        }
                        handleDecode((Result) msg.obj, barcode, scaleFactor);
                        break;
                }
            };
        };

        initViews();
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        surface.setDefaultBufferSize(width, height);
        initCameraInfo();
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        releaseCamera();
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }

    /**
     * 初始化
     */
    private void initViews() {
        mViewfinderView = findViewById(R.id.viewfinder_view);
        mViewfinderView.setZxingActivity(this);

        mTextureView = findViewById(R.id.preview_view);
        mTextureView.setSurfaceTextureListener(this);

        decodeFormats = null;
        characterSet = null;

        mDecodeThread = new DecodeThread(this, decodeFormats, decodeHints,
                characterSet, new ViewfinderResultPointCallback(getViewfinderView()));
        mDecodeThread.start();

        beepManager.updatePrefs();
    }

    private int initCameraInfo() {
        try {
            //获取摄像头管理
            mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
            String[] cameraList = mCameraManager.getCameraIdList();
            if (cameraList.length == 0) {
                Toast.makeText(this, "没有可用相机", Toast.LENGTH_LONG).show();
                return 1;
            }

            mCameraCharacteristics = mCameraManager.getCameraCharacteristics(Integer.toString(mCameraID));
            int facing = mCameraCharacteristics.get(CameraCharacteristics.LENS_FACING);

            // 获取摄像头方向
            mCameraSensorOrientation = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
            // 获取StreamConfigurationMap，它是管理摄像头支持的所有输出格式和尺寸
            StreamConfigurationMap configurationMap = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            Size[] savePicSize = configurationMap.getOutputSizes(ImageFormat.JPEG);  // 保存照片尺寸
            Size[] previewSize = configurationMap.getOutputSizes(SurfaceTexture.class); // 预览尺寸

            mSavePicSize = previewSize[0];
            mPreviewSize = new Size(PREVIEW_WIDTH, PREVIEW_HEIGHT);

            //根据屏幕的显示方向调整预览方向
            configureTransform(mPreviewSize.getWidth(), mPreviewSize.getHeight());

            mTextureView.getSurfaceTexture().setDefaultBufferSize(mSavePicSize.getWidth(), mSavePicSize.getHeight());
            //mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.JPEG, 1);
            mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.YUV_420_888, 1);
            mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mCameraHandler);

            openCamera();
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

        return 0;
    }

    static class CompareSizesByArea implements Comparator<Size> {

        @Override
        public int compare(Size lhs, Size rhs) {
            // We cast here to ensure the multiplications won't overflow
            return Long.signum((long) lhs.getWidth() * lhs.getHeight() -
                    (long) rhs.getWidth() * rhs.getHeight());
        }
    }

    private static Size chooseOptimalSize(Size[] choices, int textureViewWidth,
                                          int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {

        // Collect the supported resolutions that are at least as big as the preview Surface
        List<Size> bigEnough = new ArrayList<>();
        // Collect the supported resolutions that are smaller than the preview Surface
        List<Size> notBigEnough = new ArrayList<>();
        int w = aspectRatio.getWidth();
        int h = aspectRatio.getHeight();
        for (Size option : choices) {
            if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
                    option.getHeight() == option.getWidth() * h / w) {
                if (option.getWidth() >= textureViewWidth &&
                        option.getHeight() >= textureViewHeight) {
                    bigEnough.add(option);
                } else {
                    notBigEnough.add(option);
                }
            }
        }

        // Pick the smallest of those big enough. If there is no one big enough, pick the
        // largest of those not big enough.
        if (bigEnough.size() > 0) {
            return Collections.min(bigEnough, new CompareSizesByArea());
        } else if (notBigEnough.size() > 0) {
            return Collections.max(notBigEnough, new CompareSizesByArea());
        } else {
            Log.e("Camera2", "Couldn't find any suitable preview size");
            return choices[0];
        }
    }

    private void configureTransform(int viewWidth, int viewHeight) {
        if (null == mTextureView || null == mPreviewSize) {
            return;
        }
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        Matrix matrix = new Matrix();
        RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
        RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
        float centerX = viewRect.centerX();
        float centerY = viewRect.centerY();
        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
            float scale = Math.max(
                    (float) viewHeight / mPreviewSize.getHeight(),
                    (float) viewWidth / mPreviewSize.getWidth());
            matrix.postScale(scale, scale, centerX, centerY);
            matrix.postRotate(90 * (rotation - 2), centerX, centerY);
        } else if (Surface.ROTATION_180 == rotation) {
            matrix.postRotate(180, centerX, centerY);
        }
        mTextureView.setTransform(matrix);
    }

    /**
     * 打开相机
     */
    private void openCamera() {
        try {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "没有相机权限", Toast.LENGTH_LONG).show();
                return;
            }
            //打开摄像头
            mCameraManager.openCamera(Integer.toString(mCameraID), new CameraDevice.StateCallback() {
                @Override
                public void onOpened(CameraDevice camera) {
                    mCameraDevice = camera;
                    takePreview();  // 开启预览
                }

                @Override
                public void onDisconnected(CameraDevice camera) {//关闭摄像头
                    Log.e(TAG, "onDisconnected");
                }

                @Override
                public void onError(CameraDevice camera, int error) {//发生错误
                    Toast.makeText(getApplicationContext(), "摄像头开启失败", Toast.LENGTH_SHORT).show();
                }
            }, mCameraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     *
     */
    private ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
        @Override
        public void onImageAvailable(ImageReader reader) {
            Image image = reader.acquireNextImage();
            if (image == null)
                return;

            ByteBuffer buffer = image.getPlanes()[0].getBuffer();
            byte[] bytes = new byte[buffer.remaining()];
            buffer.get(bytes);//由缓冲区存入字节数组
            Message msg = mDecodeThread.getHandler().obtainMessage(R.id.decode, cameraResolution.x,
                    cameraResolution.y, bytes);
            //Log.d(TAG, "data.length: " + bytes.length);
            //Log.d(TAG, "cameraResolution: " + cameraResolution.x + ", " + cameraResolution.y);
            msg.sendToTarget();

            image.close();
        }
    };

    /**
     *
     */
    private CameraCaptureSession.CaptureCallback mCaptureCallBack = new CameraCaptureSession.CaptureCallback() {
        @Override
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) { //打开摄像头
            super.onCaptureCompleted(session, request, result);
            canTakePic = true;
        }

        @Override
        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) {//关闭摄像头
            super.onCaptureFailed(session, request, failure);
            Log.e(TAG, "onCaptureFailed");
            Toast.makeText(getApplicationContext(), "开启预览失败！", Toast.LENGTH_SHORT).show();
        }
    };

    /**
     * 开始预览
     */
    private void takePreview() {
        try {
            // 创建预览需要的CaptureRequest.Builder
            final CaptureRequest.Builder captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);

            Surface surface = new Surface(mTextureView.getSurfaceTexture());
            captureRequestBuilder.addTarget(surface);
            // 不增加此句ImageReader.OnImageAvailableListener的回调不会执行
            captureRequestBuilder.addTarget(mImageReader.getSurface());

            captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);      // 闪光灯
            captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // 自动对焦

            // 创建CameraCaptureSession，该对象负责管理处理预览请求和拍照请求
            mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
                    new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(CameraCaptureSession session) {
                    if (null == mCameraDevice) return;
                    // 当摄像头已经准备好时，开始显示预览
                    mCameraCaptureSession = session;
                    try {
                        mCameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), mCaptureCallBack, mCameraHandler);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
                    Toast.makeText(getApplicationContext(), "开启预览会话失败！", Toast.LENGTH_SHORT).show();
                }
            }, mCameraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        releaseCamera();
        releaseThread();
        super.onDestroy();
    }

    /**
     * releaseCamera()
     */
    private void releaseCamera() {
        if (mCameraCaptureSession != null) {
            mCameraCaptureSession.close();
            mCameraCaptureSession = null;
        }

        if (mCameraDevice != null) {
            mCameraDevice.close();
            mCameraDevice = null;
        }
        if (mImageReader != null) {
            mImageReader.close();
            mImageReader = null;
        }
    }

    /**
     * releaseThread()
     */
    private void releaseThread() {
        if (handlerThread != null)
            handlerThread.quitSafely();

        if (null != mDecodeThread) {
            Message message = Message.obtain(mDecodeThread.getHandler(), R.id.quit);
            message.sendToTarget();
            try {
                mDecodeThread.join(500L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 拍照
     */
    private void takePicture() {
        if (mCameraDevice == null || !mTextureView.isAvailable() || !canTakePic)
            return;
        try {
            // 创建拍照需要的CaptureRequest.Builder
            final CaptureRequest.Builder captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            // 将imageReader的surface作为CaptureRequest.Builder的目标
            captureRequestBuilder.addTarget(mImageReader.getSurface());

            captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
            //根据摄像头方向对保存的照片进行旋转，使其为"自然方向"
            captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, mCameraSensorOrientation);
            mCameraCaptureSession.capture(captureRequestBuilder.build(), onCaptureImageStateCallback, mCameraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private CameraCaptureSession.CaptureCallback onCaptureImageStateCallback = new CameraCaptureSession.CaptureCallback() {
        @Override
        public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) {
            super.onCaptureStarted(session, request, timestamp, frameNumber);
        }

        @Override
        public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult) {
            super.onCaptureProgressed(session, request, partialResult);
        }

        @Override
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
            super.onCaptureCompleted(session, request, result);
        }

        @Override
        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) {
            super.onCaptureFailed(session, request, failure);
        }

        @Override
        public void onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId, long frameNumber) {
            super.onCaptureSequenceCompleted(session, sequenceId, frameNumber);
        }

        @Override
        public void onCaptureSequenceAborted(CameraCaptureSession session, int sequenceId) {
            super.onCaptureSequenceAborted(session, sequenceId);
        }

        @Override
        public void onCaptureBufferLost(CameraCaptureSession session, CaptureRequest request, Surface target, long frameNumber) {
            super.onCaptureBufferLost(session, request, target, frameNumber);
        }
    };

    private void hideSystemUI() {
        View decorView = getWindow().getDecorView();
        decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                        | View.SYSTEM_UI_FLAG_IMMERSIVE);
    }

    /* for zxing */
    /**
     * A factory method to build the appropriate LuminanceSource object based on
     * the format of the preview buffers, as described by Camera.Parameters.
     *
     * @param data
     *            A preview frame.
     * @param width
     *            The width of the image.
     * @param height
     *            The height of the image.
     * @return A PlanarYUVLuminanceSource instance.
     */
    public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data,
                                                         int width, int height) {
        Rect rect = getFramingRectInPreview();
        if (rect == null) {
            return null;
        }
        // Go ahead and assume it's YUV rather than die.
        return new PlanarYUVLuminanceSource(data, width, height, rect.left,
                rect.top, rect.width(), rect.height(), false);
    }

    /**
     * Calculates the framing rect which the UI should draw to show the user
     * where to place the barcode. This target helps with alignment as well as
     * forces the user to hold the device far enough away to ensure the image
     * will be in focus. 计算这个条形码的扫描框；便于声明的同时，也强制用户通过改变距离来扫描到整个条形码
     *
     * @return The rectangle to draw on screen in window coordinates.
     */
    public synchronized Rect getFramingRect() {
        if (framingRect == null) {
            Point screenResolution = new Point(1920, 1200);
            if (screenResolution == null) {
                // Called early, before init even finished
                return null;
            }

//			int width = findDesiredDimensionInRange(screenResolution.x,
//					MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);
//			int height = findDesiredDimensionInRange(screenResolution.y,
//					MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);

            int width = findDesiredDimensionInRange(screenResolution.x,
                    MIN_FRAME_WIDTH, MAX_FRAME_WIDTH)*4/5;
            int height = findDesiredDimensionInRange(screenResolution.y,
                    MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT)*4/5;

            int leftOffset = (screenResolution.x - width) / 2;
            int topOffset = (screenResolution.y - height) / 2;
            framingRect = new Rect(leftOffset, topOffset, leftOffset + width,
                    topOffset + height);
            Log.d(TAG, "Calculated framing rect: " + framingRect);
        }
        return framingRect;
    }

    private static int findDesiredDimensionInRange(int resolution, int hardMin,
                                                   int hardMax) {
        int dim = 5 * resolution / 8; // Target 5/8 of each dimension
        if (dim < hardMin) {
            return hardMin;
        }
        if (dim > hardMax) {
            return hardMax;
        }
        return dim;
    }

    /**
     * Like {@link #getFramingRect} but coordinates are in terms of the preview
     * frame, not UI / screen.
     *
     * @return {@link Rect} expressing barcode scan area in terms of the preview
     *         size
     */
    public synchronized Rect getFramingRectInPreview() {
        if (framingRectInPreview == null) {
            Rect framingRect = getFramingRect();
            if (framingRect == null) {
                return null;
            }
            Rect rect = new Rect(framingRect);
            Point cameraResolution = new Point(1920, 1080);
            Point screenResolution = new Point(1920, 1200);
            if (cameraResolution == null || screenResolution == null) {
                // Called early, before init even finished
                return null;
            }

            /******************** 竖屏更改1(cameraResolution.x/y互换) ************************/
            rect.left = rect.left * cameraResolution.y / screenResolution.x;
            rect.right = rect.right * cameraResolution.y / screenResolution.x;
            rect.top = rect.top * cameraResolution.x / screenResolution.y;
            rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
            framingRectInPreview = rect;
        }
        return framingRectInPreview;
    }

    /**
     * 扫描成功，处理反馈信息
     *
     * @param rawResult
     * @param barcode
     * @param scaleFactor
     */
    public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {
        //inactivityTimer.onActivity();
        boolean fromLiveScan = barcode != null;
        //这里处理解码完成后的结果，此处将参数回传到Activity处理
        if (fromLiveScan) {
            beepManager.playBeepSoundAndVibrate();
            Toast.makeText(this, "扫描成功: " + rawResult.getText(), Toast.LENGTH_LONG).show();

            mDecodeHandler.removeMessages(R.id.decode);
            mDecodeHandler.removeMessages(R.id.decode_succeeded);
            mDecodeHandler.removeMessages(R.id.decode_failed);

            Intent intent = getIntent();
            intent.putExtra("codedContent", rawResult.getText());
            intent.putExtra("codedBitmap", barcode);
            Log.i(TAG, "handleDecode: " + rawResult.getText());
            //setResult(RESULT_OK, intent);
            finish();
        }
    }
}
